mod json;
mod path;
mod query;
mod valid;

pub use json::Json;
pub use json::ValidJson;
pub use path::Path;
pub use path::ValidPath;
pub use query::Query;
pub use query::ValidQuery;
pub use valid::Valid;

/// 为结构体实现[FromRequestParts]或[FromRequest]trait的宏
macro_rules! impl_from_request {
    ($name:ident, $wrapper:ident, FromRequestParts) => {
        impl<S, T> axum::extract::FromRequestParts<S> for $name<T>
        where
            S: Sync + Send,
            Valid<$wrapper<T>>: axum::extract::FromRequestParts<S, Rejection = $crate::Error>,
        {
            type Rejection = $crate::Error;

            async fn from_request_parts(
                parts: &mut axum::http::request::Parts,
                state: &S,
            ) -> Result<Self, Self::Rejection> {
                let v = Valid::from_request_parts(parts, state).await?;
                Ok($name(v.0.0))
            }
        }
    };
    ($name:ident, $wrapper:ident, FromRequest) => {
        impl<S, T> axum::extract::FromRequest<S> for $name<T>
        where
            S: Sync + Send,
            Valid<$wrapper<T>>: axum::extract::FromRequest<S, Rejection = $crate::Error>,
        {
            type Rejection = $crate::Error;

            async fn from_request(req: axum::extract::Request, state: &S) -> Result<Self, Self::Rejection> {
                let v = $crate::extractor::Valid::from_request(req, state).await?;
                Ok($name(v.0.0))
            }
        }
    };
}

impl_from_request!(ValidQuery, Query, FromRequestParts);
impl_from_request!(ValidPath, Path, FromRequestParts);
impl_from_request!(ValidJson, Json, FromRequest);